perm filename BORDER[MF,DEK] blob
sn#756279 filedate 1984-05-29 generic text, type T, neo UTF8
Computer exercise #3, due Friday May 25. CS279 Spring 1984
The purpose of this exercise is to construct a font that contains eight
characters, for making rectangular borders. The eight characters are called
NW, NM, NE, MW, ME, SW, SM, and SE (see below). Their heights are
N.height, M.height, and S.height (determined by the first letter of their name);
their widths are W.width, M.width, and E.width (determined by the second letter).
They can be fit together to make the border of a rectangle whose interior
dimensions are x*M.width by y*M.height, for any x and y:
An Important Message
Some examples of `traditional' printer's borders appear on the next page;
but use your imagination to design your own! It will be typeset on our
APS phototypesetter and used to make a souvenir of your work in this class.
Your file should be named border.mf , and it should have the following
general form:
input bbase; % read in the base file for this problem
sunrules; % use this to get boxes on the SUN screen
<Set the values of N.height, etc., using "in" or "cm" or "pt" dimensions>
<Define macros and special variables that you want to use>
vardef char.N.M =
<program that draws character N.M>
enddef;
test N.M;
vardef char.N.W =
.... and so on, for all eight characters ....
enddef;
test S.E.;
end
Here's an example file, inspired by the following border
[from American Type Founder's Pacific Coast Blue Book (1896), p. 581]:
It illustrates METAFONT's ability to generate random numbers; each
run of the following program will generate a somewhat different font!
input bbase;
% sunrules; % use this to get boxes on the SUN screen
N.height = S.height = W.width = E.width = 18pt;
M.height = M.width = 24pt;
def noise=.1pt*(normaldeviate,normaldeviate) enddef;
pen largepen;
defaultpen:=pencircle scaled .4pt;
largepen:=pencircle scaled .6pt;
def horizline expr z = % a horizontal line to the right of point z
draw z+(.5pt,0)+noise .. z+(5.5pt,0)+noise; showit enddef;
def vertline expr z = % a vertical line above point z
draw z+(0,.5pt)+noise .. z+(0,5.5pt)+noise; showit enddef;
def moveright = xx:=xx+6pt enddef; % move to next 6pt x 6pt square
def CR = xx:=x0; yy:=yy-6pt enddef; % "carriage return"
def H = % six horizontal lines
for y := .5pt step pt until 6pt: horizline (xx,yy+y); endfor;
moveright enddef;
def V = % six vertical lines
for x := .5pt step pt until 6pt: vertline (xx+x,yy); endfor;
moveright enddef;
def C = % superimpose a circle on the previous lines
path p; p=(xx-5pt,yy+3pt)+noise .. (xx-3pt,yy+5pt)+noise ..
(xx-1pt,yy+3pt)+noise .. (xx-3pt,yy+1pt)+noise .. cycle;
cullit; erase p; cullit; showit; draw p withpen largepen; showit; enddef;
vardef char.N.M =
xx:=x0:=3pt; yy:=15pt;
H; V; H; V; CR;
V; H; V; H; CR;
H; V; H; V; enddef;
test N.M;
% the example file, continued:
vardef char.N.E =
xx:=x0:=3pt; yy:=15pt;
H; V; H; CR;
V;H;C;V; CR;
H; V; H; CR;
V; H; V; enddef;
test N.E;
vardef char.N.W =
xx:=x0:=-3pt; yy:=15pt;
H; V; H; V; CR;
V;H;C;V; H; CR;
H; V; H; V; enddef;
test N.W;
vardef char.M.E =
xx:=x0:=3pt; yy:=15pt;
H; V; H; CR;
V; H; V; CR;
H; V; H; CR;
V; H; V; enddef;
test M.E;
vardef char.M.W =
xx:=x0:=-3pt; yy:=21pt;
V; H; V; CR;
H; V; H; CR;
V; H; V; CR;
H; V; H; enddef;
test M.W;
vardef char.S.M =
xx:=x0:=-3pt; yy:=9pt;
V; H; V; H; CR;
H; V; H; V; CR;
V; H; V; H; enddef;
test S.M;
vardef char.S.W =
xx:=x0:=-3pt; yy:=15pt;
V; H; V; CR;
H; V; H; CR;
V;H;C;V; CR;
H; V; H; enddef;
test S.W;
vardef char.S.E =
xx:=x0:=-3pt; yy:=9pt;
V; H; V; H; CR;
H; V;H;C;V; CR;
V; H; V; H; enddef;
test S.E;
end
% this is the file bbase.mf
% it contains the curve and stroke routines of font1base
% but not the "test" and "setwidth" macros.
delimiters (); % we seem to always start this way
ppi=722.909; % pixels per inch, on the APS (change this for other devices!)
in=ppi; % conversion factor from inches to pixels
cm=ppi/2.54; % conversion factor from centimeters to pixels
pt=ppi/72.27; % conversion factor from points to pixels
hppp:=pt; % horizontal pixels per point
vppp:=pt; % vertical pixels per point
smoothing:=1; autorounding:=2; % this adjusts curves to the raster
proofing:=1; % this says we're expecting to make proofsheets
vardef z@#=(x@#,y@#) enddef; % this defines the z convention for points
vardef dz@# = (dx@#,dy@#) enddef; % and the dx convention for directions
edges e; e=nulledges; % this initializes an empty set of pixels
pen defaultpen; defaultpen=pencircle; % and this initializes a unit pen
def fill expr c = addto e contour c withweight 1 enddef;
def erase expr c = addto e contour c withweight -1 enddef;
def draw expr p = addto e doublepath p withpen defaultpen enddef;
def showit = display e on window enddef;
def clearit = e:=nulledges enddef;
def shipit = shipout e enddef;
def cullit = cull e by (-9,1) enddef;
def autolabel = makelabel(" 5") enddef;
def makelabel(expr s)(text t) =
forsuffixes $:=t:
if not unknown z$:
special s&str$; numspecial x$; numspecial y$; fi endfor enddef;
def proofrule(expr a,b) =
special "rule"; numspecial xpart a; numspecial ypart a;
numspecial xpart b; numspecial ypart b enddef;
def labelpos(text t) =
if proofing>0:
forsuffixes $:=t: autolabel($l,$r,$); endfor fi enddef;
def clear =
numeric x[],y[],x[]l,y[]l,x[]r,y[]r,dx[],dy[];
e:=nulledges;
enddef;
% the file bbase.mf, continued:
vardef pos@#(expr length,theta) =
z@#=.5[z@#l,z@#r];
z@#r-z@#l=(length,0) rotated theta enddef;
def stroke(suffix $,$$)(expr t,lt,rt) =
fill z$l
if not unknown dz$: {dz$} fi
if t<>0: ..lt[ t[z$l,z$$l],t[z$,z$$] ]{z$$l-z$l} fi
.. z$$l
if not unknown dz$$: {dz$$} fi
& z$$l..z$$r
& z$$r
if not unknown dz$$: {-dz$$} fi
if t<>0: ..rt[ t[z$r,z$$r],t[z$,z$$] ]{z$r-z$$r} fi
.. z$r
if not unknown dz$: {-dz$} fi
& z$r..z$l & cycle;
showit; enddef;
def curve(suffix $,$$,$$$) =
fill z$l
if not unknown dz$: {dz$} fi
.. z$$l{if unknown dz$$: z$$$l-z$l else: dz$$ fi}
.. z$$$l
if not unknown dz$$$: {dz$$$} fi
& z$$$l..z$$$r
& z$$$r
if not unknown dz$$$: {-dz$$$} fi
.. z$$r{if unknown dz$$: z$r-z$$$r else: -dz$$ fi}
.. z$r
if not unknown dz$: {-dz$} fi
& z$r..z$l & cycle;
showit; enddef;
vardef test.N.@# = testit(@,@#) enddef;
vardef test.M.@# = testit(@,@#) enddef;
vardef test.S.@# = testit(@,@#) enddef;
vardef testit(suffix $,#) =
begingroup clear; h:=$.height; w:=#.width;
chardw:=w; charwd:=w/pt; charht:=h/pt;
charcode := ord str # +
(if str $ = "N": + 1 elseif str $ = "S": + 2 else: 0 fi);
proofrule ((0,0),(w,0)); proofrule ((0,h),(w,h));
proofrule ((0,0),(0,h)); proofrule ((w,0),(w,h));
char.$.#; showit; shipit; endgroup enddef;
openwindow 1 from (0,0) to (450,600) at (-20,300); window:=1;
def sunrules =
def proofrule(expr a,b)=draw a..b withpen rulepen enddef;
pen rulepen; rulepen = pencircle scaled 2;
enddef;